/* Gyroe 1.0.0 */
/* symtab.c : Add entries to the Symbol Table, calculate
   hashes and find things inside SymTab.*/

#include "euphoria.h"
#include "main-.h"
#include "sym_fields.h"

int _10hashfn(int name)
{
    int len, val;
    int _940 = 0, _943 = 0;

    object_ptr Base;
    s1_ptr ptr;

    len = SEQ_PTR(name)->length;

    ptr = SEQ_PTR(name);
    Base = ptr->base;

    /* val = name[len] * 256 + name[1]*2 + len */

    /* J.A. -> I get a segfault if I try doing it all at once.
       This is as close as I could get to the original. */

    val = *(Base + ptr->length) * 256;
    _943 = ptr->base[1] * 2 + len;

    if (IS_ATOM_INT(_943)) {
        val = _943 + len;
    }
    else {
        val = binary_op(PLUS, _943, len);
    }

    if (len >= 4) {
        if (val == (short)val)
            _943 = val * 64;
        else
            _943 = NewDouble(val * (double)64);
        if (IS_ATOM_INT(_943)) {
            val = _943 + Base[3];
        }
        else {
            val = binary_op(PLUS, _943, Base[3]);
        }
    }

    if (len >= 3) {
        if (val == (short)val)
            _943 = val * 64;
        else
            _943 = NewDouble(val * (double)64);
        if (IS_ATOM_INT(_943)) {
            val = _943 + Base[2];
        }
        else {
            val = binary_op(PLUS, _943, Base[2]);
        }
    }

    return (val % 2003) + 1;
}

int _10NewEntry(int name, int varnum, int scope, int token, int hashval, int samehash, int type_sym)
{
    int new, ptr_;
    int _970;
    int _1, _2, _3;

    s1_ptr ptr;
    object_ptr Base;

    ptr_ = NewS1(13);
    Base = ((s1_ptr)ptr_)->base;

    RefDS(_4NOVALUE);

    Base[S_OBJ] = _4NOVALUE;
    Base[S_NEXT] = 0;
    Base[S_MODE] = 1;
    Base[S_SCOPE] = scope;
    Base[S_USAGE] = 0;
    Base[S_FILE_NO] = _4current_file_no;
    Base[S_NAME] = name;
    Base[S_SAMEHASH] = samehash;
    Base[S_TOKEN] = token;
    Base[S_HASHVAL] = hashval;
    Base[S_VARNUM] = varnum;
    Base[S_INITLEVEL] = -1;
    Base[S_VTYPE] = type_sym;

    new = MAKE_SEQ(ptr_);

    Append(&_4SymTab, _4SymTab, new);

    int len;

    ptr = SEQ_PTR(_4SymTab);
    len = ptr->length;

    if (_10last_sym) {
        /* SymTab[last_sym][S_NEXT] = length(SymTab) */
        Base = ptr->base + _10last_sym;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;
        Base[S_NEXT] = len;
    }

    _10last_sym = len;
    return _10last_sym;
}

int _10tmp_alloc()
{
    int new, ptr_;
    object_ptr Base;

    ptr_ = NewS1(5);
    Base = ((s1_ptr)ptr_)->base;
    Base[S_OBJ] = 0;
    Base[S_NEXT] = 0;
    Base[S_MODE] = 0;
    Base[S_SCOPE] = 0;
    Base[S_USAGE] = 5; // M_TEMP
    new = MAKE_SEQ(ptr_);

    Append(&_4SymTab, _4SymTab, new);

    return SEQ_PTR(_4SymTab)->length;
}

int _10DefinedYet(int sym)
{
    int _1007;
    int _1, _2;
    object_ptr Base;
    s1_ptr ptr;

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + sym;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;

    _1007 = Base[S_SCOPE]; // SymTab[sym][S_SCOPE]
    _1007 = find(_1007, _1009); // SC_UNDEFUNED, SC_MULTIPLY_DEFINED, SC_PREDEF
    if (_1007 == 0) {
        if (Base[S_FILE_NO] == _4current_file_no) {
            /* Attempt to redefine %s. */
            err_add(NewString("Attempt to redefine "));
            err_add(Base[S_NAME]);
            err_add(NewString("."));
            set_err_stack();
        }
    }
}

int _10name_ext(int s)
{
    int i;
    int _1020 = 0, _1023 = 0;
    int _2;
    object_ptr Base;
    s1_ptr ptr;

    ptr = SEQ_PTR(s);
    Base = ptr->base;

    i = ptr->length;

    while (i >= 1 && find(*(Base + i), _1024) == 0) {
        i--;
    }

    rhs_slice_target = (object_ptr)&_1020;
    RHS_Slice((s1_ptr)s, i+1, ptr->length);
    return _1020;
}

int _10NewStringSym(int s)
{
    int p, tp;
    int prev = 0, search_count = 0;
    int _1, _2, _3;

    object_ptr Base;
    s1_ptr ptr;

    tp = _10literal_init;

    while (tp != 0) {
        search_count++;

        if (search_count > _10SEARCH_LIMIT)
            break;

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + tp;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        /* equal(s, SymTab[tp][S_OBJ] */
        if (compare(s, Base[1]) == 0) {
            if (tp != _10literal_init) {
                object_ptr Base2;
                s1_ptr ptr2;

                ptr = SEQ_PTR(_4SymTab);
                Base = ptr->base + prev;
                ptr = SEQ_PTR(*Base);
                Base = ptr->base;

                ptr2 = SEQ_PTR(_4SymTab);
                Base2 = ptr2->base + tp;
                ptr2 = SEQ_PTR(*Base2);
                Base2 = ptr2->base;

                /* SymTab[prev][S_NEXT] = SymTab[tp][S_NEXT] */
                Base[S_NEXT] = Base2[S_NEXT];

                /* SymTab[tp][S_NEXT] = literal_init */
                Base2[S_NEXT] = _10literal_init;

                _10literal_init = tp;
            }
            DeRefDS(s);
            return tp;
        }

        prev = tp;

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + tp;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        tp = Base[S_NEXT];

    }

    p = _10tmp_alloc();

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + p;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;

    Base[S_OBJ] = s;
    Base[S_NEXT] = _10literal_init;
    Base[S_MODE] = 2; /* M_CONSTANT */

    _10literal_init = p;

    return p;
}

int _10NewIntSym(int int_val)
{
    int i, x = 0;
    int len, new, ptr_;

    object_ptr Base;
    s1_ptr ptr;

    ptr = SEQ_PTR(_10lastintval);
    len = ptr->length + 1;
    Base = ptr->base;

    /* Try finding int_val in _10lastintval. It's possible
       we've already added it. */
    for (i = 1;i < len;i++) {
        if (int_val == *(Base + i)) {
            x = i;
            break;
        }
    }

    if (x) {
        /* Already added it, just need to find it. */
        /* lastintval stores the item, lastintsym stores
           the Symtab position. */
        ptr = SEQ_PTR(_10lastintsym);
        Base = ptr->base + x;
        return *Base;
    }

    /* Nope, make a new one. */
    ptr_ = NewS1(5);
    Base = ((s1_ptr)ptr_)->base;

    Base[S_OBJ] = int_val; // S_OBJ
    Base[S_NEXT] = 0;       // S_NEXT
    Base[S_MODE] = 2;       // S_MODE = M_CONSTANT
    Base[S_SCOPE] = 0;       // S_SCOPE
    Base[S_USAGE] = 0;       // S_USAGE

    new = MAKE_SEQ(ptr_);
    Append(&_4SymTab, _4SymTab, new);
    len = SEQ_PTR(_4SymTab)->length;

    /* Add the ref to this new int. */
    Prepend(&_10lastintval, _10lastintval, int_val);
    Prepend(&_10lastintsym, _10lastintsym, len);

    return len;
}

int _10NewDoubleSym(int d)
{
    int tp, p;
    int prev = 0, search_count = 0;
    object_ptr Base, Base3;
    s1_ptr ptr;

    tp = _10literal_init;

    //     while tp != 0 do
    while (tp != 0) {
        search_count++;

        // 	if search_count > SEARCH_LIMIT then  -- avoid n-squared algorithm
        if (search_count > _10SEARCH_LIMIT)
            break;

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + tp;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        // if d == SymTab[tp][S_OBJ]
        if (d == Base[S_OBJ]) {
            if (tp != _10literal_init) {
                object_ptr Base2;
                s1_ptr ptr2;

                ptr2 = SEQ_PTR(_4SymTab);
                Base2 = ptr2->base + prev;
                ptr2 = SEQ_PTR(*Base);
                Base2 = ptr2->base;

                // SymTab[prev][S_NEXT] = SymTab[tp][S_NEXT]
                Base[S_NEXT] = Base2[S_NEXT];

                // SymTab[tp][S_NEXT] = literal_init
                Base2[S_NEXT] = _10literal_init;

                _10literal_init = tp;
            }

            return tp;
        }

        prev = tp;

        /* We assigned Base to [tp][] before the loop. If it's here,
           it never went through since it would have returned already.
           Safe to use Base instead of redrawing. */
        // tp = SymTab[tp][S_NEXT]
        tp = Base[S_NEXT];
    }

    /* in-line tmp_alloc */
    int new, ptr_;

    ptr_ = NewS1(5);
    Base = ((s1_ptr)ptr_)->base;
    Base[S_OBJ] = d;
    Base[S_NEXT] = _10literal_init;
    Base[S_MODE] = 2; // M_CONSTANT
    Base[S_SCOPE] = 0;
    Base[S_USAGE] = 5; // M_TEMP
    new = MAKE_SEQ(ptr_);

    Append(&_4SymTab, _4SymTab, new);

    p = SEQ_PTR(_4SymTab)->length;

    _10literal_init = p;

    return p;
}

int _10NewTempSym()
{
    int p, q;
    int _1126 = 0, _1130 = 0, _1142 = 0;
    int _1, _2, _3;
    object_ptr Base;
    s1_ptr ptr;

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + _4CurrentSub;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;

    p = Base[S_TEMPS]; /* S_TEMPS */

    while (p != 0) {
        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + p;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        /* SymTab[p][S_SCOPE] == FREE */
        if (Base[S_SCOPE] == 0)
            break;

        p = Base[S_NEXT];
    }

    if (p == 0) {
        _10temps_allocated++;

        /* Do what we can in-line */

        int new, ptr_;
        object_ptr Base2;

        ptr_ = NewS1(5);
        Base2 = ((s1_ptr)ptr_)->base;

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + _4CurrentSub;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        Base2[S_OBJ] = 0; // S_OBJ
        Base2[S_NEXT] = Base[S_TEMPS]; // S_NEXT = SymTab[CurrentSub][S_TEMPS]
        Base2[S_MODE] = 3; //  M_TEMP
        Base2[S_SCOPE] = 0;
        Base2[S_USAGE] = 5; // M_TEMP

        new = MAKE_SEQ(ptr_);
        Append(&_4SymTab, _4SymTab, new);

        p = SEQ_PTR(_4SymTab)->length;

        Base[S_TEMPS] = p;
    }

    RefDS(_4NOVALUE);

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + p;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;

    // SymTab[p][S_OBJ] = NOVALUE
    Base[S_OBJ] = _4NOVALUE;

    // SymTab[p][S_SCOPE] = IN_USE
    Base[S_SCOPE] = 1;

    // SymTab[p][S_USAGE] = T_UNKNOWN
    Base[S_USAGE] = 5;

    return p;
}

int _10InitSymTab()
{
    int kname, hashval, s, st_index;
    int _1172 = 0, _1178 = 0;
    int k;
    object_ptr Base, Base2;
    s1_ptr ptr, ptr2;

    for (k = 1; k <= SEQ_PTR(_8keylist)->length; k++){
        ptr = SEQ_PTR(_8keylist);
        Base = ptr->base + k;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;
        kname = Base[1]; /* K_NAME */

        RefDS(kname);
        hashval = _10hashfn(kname);

        // st_index = NewEntry(kname,
        _1172 = Base[2];
        _1178 = Base[3];
        RefDS(kname);
        Ref(_1172);
        Ref(_1178);

        st_index = _10NewEntry(kname, 0, _1172, _1178, hashval, 0, 0);

        /* keylist[k][K_TOKEN] = PROC or FUNC or TYPE */
        if (Base[3] == 27 || Base[3] == 501 || Base[3] == 504) {
            /* Expand the entry to FIELD_MAX, set S_NUM_ARGS and S_OPCODE
               fields. */
            ptr = SEQ_PTR(_4SymTab);
            Base = ptr->base + st_index;
            ptr = SEQ_PTR(*Base);

            _1172 = Repeat(0, FIELD_MAX - ptr->length);
            Concat((object_ptr)&_1172, *Base, (s1_ptr)_1172);
            RefDS(_1172);

            *Base = _1172;

            ptr = SEQ_PTR(_4SymTab);
            Base = ptr->base + st_index;
            ptr = SEQ_PTR(*Base);
            Base = ptr->base;

            ptr2 = SEQ_PTR(_8keylist);
            Base2 = ptr2->base + k;
            ptr2 = SEQ_PTR(*Base2);
            Base2 = ptr2->base;

            /* SymTab[st_index][S_NUM_ARGS] = keylist[k][K_NUM_ARGS] */
            Base[S_NUM_ARGS] = Base2[5];

            /* SymTab[st_index][S_OPCODE] = keylist[k][K_OPCODE] */
            Base[S_OPCODE] = Base2[4];

            /* K_TOKEN = PROC and equal(kname, "_toplevel_") */
            if (_1178 == 27 && compare(kname, _856) == 0)
                _4TopLevelSub = st_index;
            else if (_1178 == 504) { /* K_TOKEN = TYPE */
                /* equal(kname, "object") */
                if (compare(kname, _716) == 0)
                    _10object_type = st_index;

                /* equal(kname, "atom") */
                else if (compare(kname, _740) == 0)
                    _10atom_type = st_index;

                /* equal(kname, "integer") */
                else if (compare(kname, _710) == 0)
                    _10integer_type = st_index;

                /* equal(kname, "sequence") */
                else if (compare(kname, _712) == 0)
                    _10sequence_type = st_index;
            }
        }

        // if buckets[hashval] = 0 then
        ptr = SEQ_PTR(_10buckets);
        Base = ptr->base;

        if (Base[hashval] == 0)
            Base[hashval] = st_index;
        else {
            s = Base[hashval];

            while (1) {
                ptr = SEQ_PTR(_4SymTab);
                Base = ptr->base + s;
                ptr = SEQ_PTR(*Base);
                Base = ptr->base;
                if (Base[S_SAMEHASH] == 0) /* SymTab[s][S_SAMEHASH] = 0 */
                    break;
                s = Base[S_SAMEHASH]; /* SymTab[s][S_SAMEHASH] */
            }

            ptr = SEQ_PTR(_4SymTab);
            Base = ptr->base + s;
            ptr = SEQ_PTR(*Base);
            Base = ptr->base;

            Base[S_SAMEHASH] = st_index; /* SymTab[s][S_SAMEHASH] = st_index */
        }

    }

    //     file_start_sym = length(SymTab)
    _4file_start_sym = SEQ_PTR(_4SymTab)->length;

    DeRef(kname);
    DeRef(_1172);
    DeRef(_1178);
}

int _10keyfind(int word, int file_no)
{
    int defined, hashval, scope, st_ptr;
    int gtok = 0, tok = 0;
    int _1328;
    int _1, _2;
    int ptr_;
    object_ptr Base, Base2;
    s1_ptr ptr;

    RefDS(_39);
    DeRefi(_10dup_globals);
    _10dup_globals = _39;

    hashval = _10hashfn(word);

    ptr = SEQ_PTR(_10buckets);
    Base = ptr->base + hashval;

    st_ptr = *Base;

    while (st_ptr) {
        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + st_ptr;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        /* equal(word, SymTab[st_ptr][S_NAME]) */
        if (compare(word, Base[7]) == 0) {
            // tok = {SymTab[st_ptr][S_TOKEN], st_ptr}
            ptr_ = NewS1(2);
            Base2 = ((s1_ptr)ptr_)->base;
            Base2[1] = Base[S_TOKEN];
            Base2[2] = st_ptr;
            tok = MAKE_SEQ(ptr_);

            if (file_no == -1) {
                scope = Base[S_SCOPE]; // SymTab[st_ptr][S_SCOPE]

                if (scope == 6) { /* SC_GLOBAL */
                    /* current_file_no = SymTab[st_ptr][S_FILE_NO] */
                    if (_4current_file_no == Base[S_FILE_NO]) {
                        DeRef(gtok);
                        return tok;
                    }

                    RefDS(tok);
                    DeRef(gtok);
                    gtok = tok;

                    Append(&_10dup_globals, _10dup_globals, st_ptr);
                }
                else if (scope == 5) { /* SC_LOCAL */
                    /* current_file_no = SymTab[st_ptr][S_FILE_NO] */
                    if (_4current_file_no == Base[S_FILE_NO]) {
                        DeRef(gtok);
                        return tok;
                    }
                }
                else if (scope == 7) { /* SC_PREDEF */
                    if (SEQ_PTR(_10dup_globals)->length == 0) {
                        DeRef(gtok);
                        return tok;
                    }
                }
                else {
                    // return tok -- keyword, private
                    DeRef(gtok);
                    return tok;
                }
            }
            else {
                /* file_no = SymTab[st_ptr][S_FILE_NO] and SymTab[st_ptr][S_SCOPE] = SC_GLOBAL */
                if (file_no == Base[S_FILE_NO] && Base[S_SCOPE] == 6) {
                    DeRef(gtok);
                    return tok;
                }
            }
        }

        // st_ptr = SymTab[st_ptr][S_SAMEHASH]
        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + st_ptr;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;
        st_ptr = Base[S_SAMEHASH];
    }

    if (SEQ_PTR(_10dup_globals)->length == 1) {
        DeRef(tok);
        return gtok;
    }

    if (SEQ_PTR(_10dup_globals)->length == 0)
        defined = 9; // SC_UNDEFINED
    else
        defined = 10; // SC_MULTIPLY_DEFINED

    //     tok = {VARIABLE, NewEntry(word, 0, defined,
    _2 = (int)SEQ_PTR(_10buckets);
    _1328 = (int)*(((s1_ptr)_2)->base + hashval);
    Ref(_1328);
    RefDS(word);
    Ref(_1328);
    _1328 = _10NewEntry(word, 0, defined, -100, hashval, _1328, 0);
    DeRef(tok);
    _1 = NewS1(2);
    _2 = (int)((s1_ptr)_1)->base;
    ((int *)_2)[1] = -100;
    ((int *)_2)[2] = _1328;
    tok = MAKE_SEQ(_1);

    //     buckets[hashval] = tok[T_SYM]
    ptr = SEQ_PTR(_10buckets);
    Base = ptr->base + hashval;
    ptr = SEQ_PTR(tok);
    *Base = *(ptr->base + 2); // buckets[hashval] = tok[T_SYM]

    //     return tok  -- no ref on newly declared symbol
    DeRef(gtok);
    return tok;
}

int _10Hide(int s)
{
    int p, prev = 0;

    object_ptr Base, Base2;
    s1_ptr ptr, ptr2;

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + s;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base; // SymTab[s]

    ptr2 = SEQ_PTR(_10buckets);
    Base2 = ptr2->base + Base[S_HASHVAL]; // buckets[SymTab[s][S_HASHVAL]]
    p = *Base2;

    while (1) {
        if (p == 0 || p == s)
            break;

        prev = p;

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + p;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        p = Base[S_SAMEHASH]; // SymTab[p][S_SAMEHASH]
    }

    if (p == 0) {
        /* Already hidden */
        return 0;
    }

    //     if prev = 0 then
    if (prev == 0) {
        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + s;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        ptr2 = SEQ_PTR(_10buckets);
        Base2 = ptr2->base + Base[S_HASHVAL]; // buckets[SymTab[s][S_HASHVAL]]
        *Base2 = Base[S_SAMEHASH]; // SymTab[s][S_SAMEHASH]
    }
    else {
        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + prev;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base; // SymTab[prev][S_SAMEHASH]

        ptr2 = SEQ_PTR(_4SymTab);
        Base2 = ptr2->base + s;
        ptr2 = SEQ_PTR(*Base2);
        Base2 = ptr2->base; // SymTab[s][S_SAMEHASH]

        Base[S_SAMEHASH] = Base2[S_SAMEHASH];
    }
}

void DOEXIT()
{
DeRefDS(_4SymTab);
DeRefDS(_4SymTab);
DeRefDS(_4SymTab);
DeRefDS(_4SymTab);
DeRefDS(_4SymTab);
DeRefDS(_4SymTab);
}


int _10LintCheck(int s)
/* See if stuff has gone unused or unread and, if so,
   find out where it is. Only called if warning is on. */
{
    int file = 0, place, problem, vtype = 0;
    int n, u;
    int _1385;
    int _1360 = 0, _1387 = 0;
    int _1, _2;
    object_ptr Base;
    s1_ptr ptr;

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + s;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;
    u = Base[S_USAGE];

    // file = name_ext(file_name[current_file_no])
    ptr = SEQ_PTR(_4file_name);
    Base = ptr->base + _4current_file_no;
    file = _10name_ext(*Base);

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + s;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;

    // SymTab[s][S_SCOPE] == SC_LOCAL
    if (Base[S_SCOPE] == 5) {
        // SymTab[s][S_MODE] == M_CONSTANT
        if (Base[S_MODE] == 2) {
            // vtype = "local constant"
            RefDS(_1370);
            vtype = _1370;
        }
        else {
            // vtype = "local variable"
            RefDS(_1371);
            DeRefi(vtype);
            vtype = _1371;
        }

        // place = ""
        RefDS(_39);
        place = _39;
    }
    else {
        // vtype = "private variable"
        RefDS(_1378);
        DeRefi(vtype);
        vtype = _1378;

        // place = SymTab[CurrentSub][S_NAME]
        object_ptr Base2;

        ptr = SEQ_PTR(_4SymTab);
        Base2 = ptr->base + _4CurrentSub;
        ptr = SEQ_PTR(*Base2);
        Base2 = ptr->base;

        place = Base2[S_NAME];
        RefDS(place);
    }

    // problem = ""
    RefDS(_39);
    problem = _39;

    if (u < 1) { /* Either 0(unused) or 1(not assigned) */
        if (u == 0) { /* U_UNREAD */
            RefDS(_1388);
            DeRefi(problem);
            problem = _1388;
        }
        else if (u == 1) { /* U_READ */
            RefDS(_1390);
            DeRefi(problem);
            problem = _1390;
        }

        if (SEQ_PTR(problem)->length) {
            if (SEQ_PTR(place)->length) {
                /* %s %s in %s() in %s is %s */

                err_add(vtype);
                err_add(NewString(" "));
                err_add(Base[S_NAME]);
                err_add(NewString(" in "));
                err_add(place);
                err_add(NewString("() in "));
                err_add(file);
                err_add(NewString(" is "));
                err_add(problem);

                RefDS(error_stack);
                _6Warning(error_stack);

                RefDS(_39);
                error_stack = _39;
            }
            else {
                /* %s %s in %s is %s" */
                err_add(vtype);
                err_add(NewString(" "));
                err_add(Base[S_NAME]);
                err_add(NewString(" in "));
                err_add(file);
                err_add(NewString(" is "));
                err_add(problem);
                RefDS(error_stack);
                _6Warning(error_stack);

                RefDS(_39);
                error_stack = _39;
            }
        }
    }

}

int _10HideLocals()
/* Exiting from a file. Lint check and hide the local vars. */
{
    int s;

    object_ptr Base;
    s1_ptr ptr;

    s = _4file_start_sym;

    while (1) {
        if (s == 0)
            break;

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + s;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        // SymTab[s][S_SCOPE] == SC_LOCAL && SymTab[s][S_FILE_NO] == _4current_file_no
        if (Base[S_SCOPE] == 5 && Base[S_FILE_NO] == _4current_file_no) {
        /* Keep with the LOCALS, and within this file number. */
            _10Hide(s);
            // SymTab[s][S_TOKEN] = VARIABLE and (with warning)
            if (Base[S_TOKEN] == -100 && _4OpWarning)
                _10LintCheck(s);
        }

        // SymTab[s][S_NEXT]
        s = Base[S_NEXT];
    }
}

int _10ExitScope()
/* Current routine is exiting. Hide all it's var's. 
   While we're at it, do some lint checking. */
{
    int s;

    object_ptr Base;
    s1_ptr ptr;

    ptr = SEQ_PTR(_4SymTab);
    Base = ptr->base + _4CurrentSub;
    ptr = SEQ_PTR(*Base);
    Base = ptr->base;

    s = Base[S_NEXT]; // SymTab[CurrentSub][S_NEXT]

    while (1) {
        if (s == 0)
            break;
        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + s;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;
        if (Base[S_SCOPE] != 3) // SymTab[s][S_SCOPE] != SC_PRIVATE
            break;

        _10Hide(s);

        if (_4OpWarning)
            _10LintCheck(s);

        ptr = SEQ_PTR(_4SymTab);
        Base = ptr->base + s;
        ptr = SEQ_PTR(*Base);
        Base = ptr->base;

        s = Base[S_NEXT]; // SymTab[s][S_NEXT]
    }
}

